package cn.pconline.autoclub.task.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import cn.pconline.autoclub.task.FileUtils;


public class TokenUtils {
		//得到配置文件中的代理信息、融云配置信息
		private static final String PROXY_URL = FileUtils.getConfig("sys.proxyUrl");
		private static final int PROXY_PORT = FileUtils.getConfig("sys.proxyPort",8080);
		private static final String APP_KEY = FileUtils.getConfig("sys.appKey");
		private static final String APP_SECRET = FileUtils.getConfig("sys.appSecret");
		private static final String RONG_CLOUD_JOIN_URL = FileUtils.getConfig("sys.rongcloudJoinUrl");
		//生成随机数
		private static final SecureRandom random = new SecureRandom();
		private static final Logger log = LoggerFactory.getLogger(TokenUtils.class);
		
		/**
		 * 申请加入聊天群（业务逻辑）
		 * @param userId
		 * @param clubId
		 * @param clubName
		 * @return
		 * @throws ApiException
		 */
		public static boolean joinClub(String userId, String clubId, String clubName) throws ApiException{
			String string = join(APP_KEY, APP_SECRET, PROXY_URL, PROXY_PORT, userId, clubId, clubName, RONG_CLOUD_JOIN_URL);
			try {
				JSONObject jsonObject = JSONObject.parseObject(string);
				int code = jsonObject.getIntValue("code");
				if(code == 200) {
					return true;
				} else if(code == 504) {
					log.error("调用融云Join接口,消息服务处理超时 !");
					return false;
				} else if(code == 502) {
					log.error("调用融云Join接口,消息服务不可用 !");
					return false;
				} else {
					log.error("调用融云Join接口,未知错误 !");
					return false;
				}
			} catch(Exception exception) {
				log.error("调用融云Join接口失败！", exception);
				return false;
			}
		}
		
		/**
		 * 申请退出聊天群（业务逻辑）
		 * @param userId
		 * @param clubId
		 * @return
		 * @throws ApiException
		 */
		public static boolean QuitClub(String userId, String clubId) throws ApiException {
			String string = quit(APP_KEY, APP_SECRET, PROXY_URL, PROXY_PORT, userId, clubId, RONG_CLOUD_JOIN_URL);
			try {
				JSONObject jsonObject = JSONObject.parseObject(string);
				int code = jsonObject.getIntValue("code");
				if(code == 200) {
					//log.info("调用融云Quit接口,成功操作 !");
					return true;
				} else if(code == 504){
					log.error("调用融云Quit接口,消息服务处理超时 !");
					return false;
				} else if(code == 502) {
					log.error("调用融云Quit接口,消息服务不可用 !");
					return false;
				} else {
					log.error("调用融云Quit接口,未知错误 !");
					return false;
				}
			} catch(Exception exception) {
				log.error("调用融云Quit接口失败！", exception);
				return false;
			}
		}
		
		
		/**
		 * 申请加入融云群
		 * @param appKey
		 * @param appSecret
		 * @param proxyUrl
		 * @param proxyPort
		 * @param userId
		 * @param groupId
		 * @param groupName
		 * @param rongcloudJoinUrl
		 * @return
		 * @throws ApiException
		 */
		public static String join(String appKey, String appSecret, String proxyUrl, int proxyPort, String userId, String groupId, String groupName, String rongcloudJoinUrl) throws ApiException {
			
			StringBuilder sb = new StringBuilder("userId=");
			try {
				sb.append(URLEncoder.encode(userId, "UTF-8"));
				sb.append("&groupId=").append(URLEncoder.encode(groupId, "UTF-8"));
				sb.append("&groupName=").append(URLEncoder.encode(groupName, "UTF-8"));
			} catch (Exception ignore) {}
			
			return doRongApiPost(appKey, appSecret, proxyUrl, proxyPort, rongcloudJoinUrl, sb.toString());
		}
		
		/**
		 * 申请退出融云群
		 * @param appKey
		 * @param appSecret
		 * @param proxyUrl
		 * @param proxyPort
		 * @param userId
		 * @param groupId
		 * @param rongcloudQuitUrl
		 * @return
		 * @throws ApiException
		 */
		public static String quit(String appKey, String appSecret, String proxyUrl, int proxyPort, String userId, String groupId, String rongcloudQuitUrl) throws ApiException {
			
			StringBuilder sb = new StringBuilder("userId=");
			try{
				sb.append(URLEncoder.encode(userId, "UTF-8"));
				sb.append("&groupId=").append(URLEncoder.encode(groupId, "UTF-8"));
			}catch(Exception ignore){}
			
			return doRongApiPost(appKey, appSecret, proxyUrl, proxyPort, rongcloudQuitUrl, sb.toString());
		}
		
		/**
		 * 融云相关接口入口 
		 * @param appKey
		 * @param appSecret
		 * @param apiUrl
		 * @param postParams
		 * @return
		 * @throws ApiException
		 */
		private static String doRongApiPost(String appKey, String appSecret, String proxyUrl, int proxyPort, String apiUrl, String postParams) throws ApiException {
			StringBuilder retSb = null;
			HttpURLConnection conn = null;
			
			try {
				//判断是否需要代理连接
				if(proxyUrl != null && proxyPort > 0 && !"".equals(proxyUrl) ) {
					Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyUrl, proxyPort));
					conn = (HttpURLConnection) new URL(apiUrl).openConnection(proxy);
				} else {
					conn = (HttpURLConnection) new URL(apiUrl).openConnection();
				}
				
				conn.setDoOutput(true);
				conn.setDoInput(true);
				conn.setUseCaches(false);
				HttpURLConnection.setFollowRedirects(true);
				conn.setInstanceFollowRedirects(true);
				conn.setRequestMethod("POST");
				
				String nonce = new DecimalFormat("000000").format(random.nextInt(100000));
				String timestamp = String.valueOf(System.currentTimeMillis());
				
				//签名=SHA-1（appSecret + 随机数 + 时间戳）
				StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
				
				conn.setRequestProperty("App-Key", appKey);
				conn.setRequestProperty("Timestamp", timestamp);
				conn.setRequestProperty("Nonce", nonce);
				conn.setRequestProperty("Signature", hexSHA1(toSign.toString()));
				
				conn.setRequestProperty("Content-Type",
						"Application/x-www-form-urlencoded");
				
				if(postParams != null){
					OutputStream out = conn.getOutputStream();
					out.write(postParams.getBytes("UTF-8"));
					out.flush();
					out.close();
				}
				
				if(conn.getResponseCode() == 200){
					BufferedReader reader = new BufferedReader(new InputStreamReader(
							conn.getInputStream()));
		
					retSb = new StringBuilder();
					String line;
					while ((line = reader.readLine()) != null) {
						retSb.append(line);
					}
					reader.close();
				}else{
					BufferedReader reader = new BufferedReader(new InputStreamReader(
							conn.getErrorStream()));
					
		
					retSb = new StringBuilder();
					String line;
					while ((line = reader.readLine()) != null) {
						retSb.append(line);
					}
					reader.close();
					throw new ApiException(conn.getResponseCode(), retSb == null ? null : retSb.toString(), null); 
				}
			} catch (Exception ex) {
				if(ex instanceof ApiException){
					throw (ApiException)ex;
				}else{
					throw new ApiException(502, ex.getMessage(), ex);
				}
			} finally {
				try{
				conn.disconnect();
				}catch(Exception ignore){}
			}
			return retSb == null ? null : retSb.toString();
		}
		
		/**
		 * 将字条串转换为SHA-1码
		 * @param value
		 * @return
		 */
		public static String hexSHA1(String value) {
			try {
				MessageDigest md = MessageDigest.getInstance("SHA-1");
				md.update(value.getBytes("utf-8"));
				byte[] digest = md.digest();
				return byteToHexString(digest);
			} catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}
		
		/**
		 * 将字条串转换为SHA-1码（逻辑实现）
		 * @param bytes
		 * @return
		 */
		public static String byteToHexString(byte[] bytes) {
	        StringBuilder sb = new StringBuilder();  
	        for (int n = 0; n < bytes.length; n++) {  
	            String stmp = Integer.toHexString(bytes[n] & 0xFF);
	            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);  
	        }  
	        return sb.toString().toUpperCase().trim();
		}
}
